
/* Function.prototype的属性:
 * name : 表示函数名称
 * length : 表示函数形参个数
 * arguments : 表示调用函数时实际传入的参数组成的类数组对象(instance-level) (函数执行期间，在函数内部使用)
 *              arguments.length 表示实际传入的参数个数
 *              arguments.callee 表示当前函数的引用
 * caller : 表示函数的调用者 (函数执行期间，在函数内部使用)
 * constructor : 将函数本身当作实例对待时，这个实例是采用哪个构造函数创建的，就获取哪个构造函数
 * apply()
 * bind()
 * call()
 * toString() 用以获得函数的源码(以字符串形式返回)
 */

// 采用"函数声明"定义的函数其名称就是function之后、()之前书写的名称
function welcome(){
    console.log( '我是Function类的实例' ); 
}

// 将 welcome 变量中存储的 引用 赋值给 x 变量
let x = welcome ;
console.log( x.name ); // name 表示函数本身的名称

console.log( '- - - - - - - - - - - - - - - - - - - -' );

// 采用"函数表达式" 声明的函数，其函数名就是首次付给的那个变量名
let hello = function( name ){
    console.log( '你好，' + name );
}
let y = hello ;
console.log( y.name , y.length ); // length 表示函数形参个数

console.log( '- - - - - - - - - - - - - - - - - - - -' );

function first(){
    console.log( 'first' , first.caller ); // caller 函数的调用者
}

function second(){
    console.log( 'second');
    first();
}

second();

console.log( '- - - - - - - - - - - - - - - - - - - -' );

function add(a,b){
    // 函数运行期间，在函数内可以通过argumens来获得各个实参
    console.log( 'arguments: ' , arguments );
    console.log( 'arguments.length: ' , arguments.length ); // 实际传入的参数个数
    console.log( 'arguments.calee: ' , arguments.callee ); // 当前函数的引用
    let c = a + b ;
    return c ;
}

add(); // { }

add( 10, 20 );

add( 10 , 20, 30, 40 , 50 );

/*
let haha = { 'length': 2 , '0' : 20 , '1' : 30  }
for( let i = 0 ; i < haha.length ; i++ ){
    console.log( haha[ i ] );
}
*/

console.log( '- - - - - - - - - - - - - - - - - - - -' );

let s = add.toString();
console.log( s );

console.log( '- - - - - - - - - - - - - - - - - - - -' );

console.log( add.constructor ); // [Function: Function]
// function Object(){ }
console.log( Object.constructor ); // [Function: Function]
// function Function(){ }
console.log( Function.constructor ); // [Function: Function]